package com.itmake.sample.datascope.aspectj;

import com.itmake.sample.datascope.annotation.DataScope;
import com.itmake.sample.datascope.enums.DataScopeEnum;
import com.itmake.sample.datascope.handler.DataScopeHandler;
import com.itmake.sample.datascope.model.bo.ActiveRoleBo;
import com.itmake.sample.datascope.model.bo.ActiveUserBo;
import com.itmake.sample.datascope.service.IObtainUserService;
import com.itmake.sample.datascope.sql.DataScopeSql;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 数据过滤处理
 *
 * @author Amjacks
 * @since 2023/08/10
 */
@Aspect
@Component
public class DataScopeAspect {

    @Resource
    private IObtainUserService iObtainUserService;

    @Before("@annotation(ds)")
    public void doBefore(JoinPoint joinPoint, DataScope ds) {
        // 获取当前的用户
        ActiveUserBo activeUserBo = iObtainUserService.getActiveUser();
        // 如果是超级管理员，则不过滤数据
        StringBuilder sqlString = new StringBuilder();
        if (Objects.nonNull(activeUserBo) && !activeUserBo.isAdmin()) {
            for (ActiveRoleBo role : activeUserBo.getRoles()) {
                String dataScope = role.getDataScope();
                if (dataScope.equals(DataScopeEnum.DATA_SCOPE_ALL.getCode())) {
                    sqlString = new StringBuilder();
                    break;
                } else if (dataScope.equals(DataScopeEnum.DATA_SCOPE_SELF.getCode())) {
                    sqlString.append(DataScopeEnum.buildSelf(ds.userAlias(), activeUserBo.getUserId()));
                }
            }
        }
        // 设置当前线程的数据权限字符串
        DataScopeHandler.set(sqlString.toString());
        // 如果最后一个参数是 DataScopeSql 则注入 sql 语句
        Object[] args = joinPoint.getArgs();
        Object lastArg = args[joinPoint.getArgs().length - 1];
        if (lastArg instanceof DataScopeSql) {
            DataScopeSql dataScopeSql = (DataScopeSql) lastArg;
            dataScopeSql.setSql(sqlString.toString());
        }
    }

    @After("@annotation(ds)")
    public void doAfter(JoinPoint joinPoint, DataScope ds) {
        // 移除当前线程的数据权限字符串
        DataScopeHandler.remove();
    }
}
